package com.rabbit.mq.service;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.UUID;

/**
 * 普通的消息队列
 */
@Service
public class RabbitPublisher implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setReturnCallback(this);
        rabbitTemplate.setConfirmCallback(this);
    }

    /**
     * 接收发送后确认信息
     *
     * CorrelationData correlationData：可以封装业务ID信息，需要在发送消息时传入此参数，这里才能接收到，否则是null
     * boolean ack：消息发送的结果状态，发送成功是true，失败是false
     * tring cause：发送失败的描述信息，如果发送成功是null。
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            System.err.println("RabbitPublisher ack send succeed: " + correlationData);
        } else {
            System.err.println("RabbitPublisher ack send failed: " + correlationData + "|" + cause);
        }
    }

    /**
     * 发送失败的回调
     *
     * Message message：发送的消息内容 + 发送消息的配置信息
     * int replyCode：状态码，发送成功是200
     * String replyText：发送消息失败的描述信息
     * String exchange：消息使用的交换机
     * String routingKey：消息使用的路由键
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.err.println("ack " + message + " 发送失败");
    }


    /**
     *
     * @param exchange
     * @param routing
     * @param message
     * @return
     */
    public String publish(String exchange, String routing, String message) {

        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend(exchange, routing, message, correlationData);
        return message;
    }

    /**
     *
     * @param routing
     * @param message
     * @return
     */
    public String publish(String routing, String message) {

        return this.publish("", routing, message);
    }
}
